package com.funcpro.common.Response;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.funcpro.common.eums.ResponseEum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author ZYT
 * @desc
 * @time 2023-06-06 10:06
 */
@Builder
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class BaseResponse<T> implements Serializable {
    private String code;
    private Boolean success;
    private String msg;
    private T data;
    private List<String> errors;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime time;

    private static BaseResponse<Boolean> result(ResponseEum responseEum) {
        return result(responseEum, null);
    }

    private static <T> BaseResponse<T> result(ResponseEum responseEum, T data) {
        return result(responseEum, null, data, null);
    }

    private static <T> BaseResponse<T> result(ResponseEum responseEum, String message, T data, List<String> errors) {
        boolean success = false;
        if (responseEum.getCode().equals("200")) {
            success = !success;
        }
        String apiMessage = responseEum.getMessage();
        try {
            apiMessage = new String(apiMessage.getBytes(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (StringUtils.isBlank(message)) {
            message = apiMessage;
        }
        return (BaseResponse<T>) BaseResponse.builder()
                .code(responseEum.getCode())
                .msg(message)
                .data(data)
                .success(success)
                .time(LocalDateTime.now())
                .build();
    }

    public static BaseResponse<JSONObject> ok() {
        return ok(new JSONObject());
    }

    public static <T> BaseResponse<T> ok(T data) {
        return result(ResponseEum.OK, data);
    }

    public static <T> BaseResponse<T> ok(String message, T data) {
        return result(ResponseEum.OK, message, data, null);
    }

    public static BaseResponse<JSONObject> fail() {
        return fail(ResponseEum.INTERNAL_SERVER_ERROR);
    }

    public static BaseResponse<JSONObject> fail(ResponseEum responseEum) {
        return result(responseEum, new JSONObject());
    }

    public static BaseResponse<JSONObject> fail(String message) {
        return result(ResponseEum.INTERNAL_SERVER_ERROR, message, new JSONObject(), null);
    }

    public static BaseResponse<JSONObject> fail(ResponseEum responseEum, String message) {
        return result(responseEum, message, new JSONObject(), null);
    }

    public static BaseResponse<JSONObject> fail(ResponseEum responseEum, String message, List<String> errors) {
        return result(responseEum, message, new JSONObject(), errors);
    }

}
